using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace GetTogether.Studio.WebService
{
    public class Util
    {
        public static string GetInvokeHistoryPath(string projName, string userCode, string methodName, string historyName)
        {
            string path = GetTogether.Studio.ProjectParameter.GetSettingsPath(GetTogether.Studio.ProjectParameter.ProjectCategory.WebService, userCode);
            path = System.IO.Path.Combine(path, string.Concat(projName, "(History)\\", methodName));
            string htyName = historyName;
            if (string.IsNullOrEmpty(htyName)) htyName = "Recent";
            path = System.IO.Path.Combine(path, htyName);
            return path;
        }

        public static string GetInvokeHistoryParameterFile(string projName, string userCode, string methodName, string historyName, string pName)
        {
            return System.IO.Path.Combine(GetInvokeHistoryPath(projName, userCode, methodName, historyName), string.Concat(pName, ".txt"));
        }

        public static string InvokeByShare(string userCode, string MethodName, string projectName, string shareFrom, string historyName)
        {
            GetTogether.Studio.WebService.ProjectParameter Parameter = GetTogether.Studio.ProjectParameter.GetSettingsByProjectName<ProjectParameter>(GetTogether.Studio.ProjectParameter.ProjectCategory.WebService, userCode, projectName, shareFrom);
            Wsdl CurrentWsdl = WebServiceHelper.GetWsdl(Parameter, false);
            string retXml = string.Empty;
            StringBuilder sbParameter = new StringBuilder();
            DateTime startDt = DateTime.Now;
            try
            {
                System.Reflection.MethodInfo mi = CurrentWsdl.GetMethodByName(MethodName);
                string rqtModeXml = System.IO.File.ReadAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, "[Request-Mode]"));
                MethodSetting methodSetting = GetTogether.Utility.SerializationHelper.FromXml<MethodSetting>(rqtModeXml);
                //methodSetting.RqtMode = MethodSetting.RequestMode.Object;

                string historyPath = GetInvokeHistoryPath(projectName, userCode, MethodName, historyName);
                if (!System.IO.Directory.Exists(historyPath)) System.IO.Directory.CreateDirectory(historyPath);
                System.IO.File.WriteAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, "[Request-Mode]"),
                    GetTogether.Utility.SerializationHelper.SerializeToXml(methodSetting));
                if (methodSetting.RqtMode == MethodSetting.RequestMode.Object)
                {
                    List<object> parameters = new List<object>();
                    List<object> referenceObjects = new List<object>();
                    foreach (System.Reflection.ParameterInfo pi in mi.GetParameters())
                    {
                        if (sbParameter.Length > 0) sbParameter.AppendLine("\r\n-----------------------------------------------------------------------------");
                        string rqtValue = System.IO.File.ReadAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, pi.Name));
                        sbParameter.Append(pi.Name).Append(":").Append(rqtValue);
                        object p = WsdlHelper.ConvertParameter(CurrentWsdl, pi, rqtValue);
                        if (pi.ParameterType.IsByRef)
                        {
                            referenceObjects.Add(p);
                        }
                        parameters.Add(p);
                        if (!System.IO.Directory.Exists(historyPath)) System.IO.Directory.CreateDirectory(historyPath);
                        System.IO.File.WriteAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, pi.Name), WsdlHelper.ParameterToString(p));
                    }
                    foreach (FieldInfo fi in CurrentWsdl.GetHeaders(mi))
                    {
                        string rqtValue = System.IO.File.ReadAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, fi.Name));
                        if (sbParameter.Length > 0) sbParameter.AppendLine("\r\n-----------------------------------------------------------------------------");
                        sbParameter.Append(fi.Name).Append("(Header):").Append(rqtValue);

                        object p = WsdlHelper.ConvertParameter(CurrentWsdl, fi, rqtValue);
                        if (fi.FieldType.IsByRef)
                        {
                            referenceObjects.Add(p);
                        }
                        GetTogether.Mapping.ObjectHelper.SetValue(CurrentWsdl.ServiceObject, fi.Name, p);
                        fi.SetValue(CurrentWsdl.ServiceObject, p);
                        if (!System.IO.Directory.Exists(historyPath)) System.IO.Directory.CreateDirectory(historyPath);
                        System.IO.File.WriteAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, fi.Name), WsdlHelper.ParameterToString(p));
                    }
                    object ret = CurrentWsdl.Invoke(MethodName, parameters.Count > 0 ? parameters.ToArray() : null);
                    if (ret == null)
                        retXml = "";
                    else
                    {
                        if (Parameter.AddressType == AddressType.WebService)
                            retXml = GetTogether.Utility.SerializationHelper.SerializeToXml(ret);
                        else
                            retXml = (string)ret;
                    }
                    if (referenceObjects.Count > 0)
                    {
                        retXml += "\r\n-----------------------------------------------------------------------------";
                        retXml += "\r\nBy Reference Object(s)";
                        retXml += "\r\n-----------------------------------------------------------------------------";

                        foreach (object obj in referenceObjects)
                        {
                            retXml += "\r\n" + GetTogether.Utility.SerializationHelper.SerializeToXml(obj);
                        }
                    }
                }
                else
                {
                    string requestXml = System.IO.File.ReadAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, "[SOAP-Request]"));
                    sbParameter.Append("SOAP Request:").Append(requestXml);
                    sbParameter.AppendLine("-----------------------------------------------------------------------------");
                    retXml = RequestHelper.SendWebRequest(Parameter, mi, requestXml);
                    System.IO.File.WriteAllText(GetInvokeHistoryParameterFile(projectName, userCode, MethodName, historyName, "[SOAP-Request]"), requestXml);
                }
            }
            catch (Exception ex)
            {
                retXml = ex.ToString();
            }
            string duration = DateTime.Now.Subtract(startDt).ToString();
            if (sbParameter.Length == 0) sbParameter.Append("-");
            string info = string.Format(
@"Duration:{0}({4} to {5}),Length:{1}
=============================================================================
{2}
=============================================================================
{3}", duration, GetTogether.Utility.StringHelper.GetSizeString(retXml.Length.ToString()), sbParameter.ToString(), string.IsNullOrEmpty(retXml) ? "-" : retXml, startDt.ToString("dd HH:mm:ss"), DateTime.Now.ToString("dd HH:mm:ss"));
            return info;
        }
    }
}
